<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <script>
        // 深拷贝：引用类型的改变不影响原理的那一个
        const obj1 = {
            age: 20,
            name: 'xxx',
            address: {
                city: 'beijing'
            },
            arr: ['a', 'b', 'c']
        }

        function deepClone(obj = {}) {
            if(obj instanceof RegExp) {
                return new RegExp(obj);
            }
            if(obj instanceof Date) {
                return new Date(obj);
            }
            // obj不是对象或者为空，直接返回
            if (obj === null || typeof obj !== 'object') {
                return obj;
            }
            let result;
            if (obj instanceof Array) {
                result = [];
            } else {
                result = {}
            }

            for (let key in obj) {
                // 保证key不是原型属性
                if (obj.hasOwnProperty(key)) {
                    result[key] = deepClone(deepClone(obj[key]))
                }
            }
            return result
        }
        // 利用json方法实现深拷贝
        // 但是这里要注意的是，你只能使用这种方法拷贝 JavaScript 原生的数据类型（非自定义数据类型）。
        // 而且存在问题：
        // 会忽略 undefined
        // 会忽略 symbol
        // 不能序列化函数
        // 不能解决循环引用的对象
        // const obj2 = JSON.parse(JSON.stringify(obj1))
        const obj2 = deepClone(obj1)
        obj2.address.city = 'guangzhou';
        console.log(obj1.address.city);

        function deepClone2(obj) {
            if(obj instanceof RegExp) {
                return new RegExp(obj)
            }
            if(obj instanceof Date) {
                return new Date(obj)
            }
            if(obj === null || typeof obj !== 'object') {
                return obj;
            }
            let res ;
            if(obj instanceof Array) {
                res = []
            }else {
                res = {};
            }
            for(let key in obj) {
                if(obj.hasOwnProperty(key)) {
                    res[key] = deepClone2(obj[key])
                }
            }
            return res;
        }
    </script>
</body>

</html>